Wmctrl
Скрестить мощь скриптов и красоту графики поможет wmctrl. С его помощью можно изменять размер и расположение окон на экране, автоматизировать смену рабочих столов или использовать информацию об открытых окнах в других скриптах.
Основное преимущество wmctrl — полная независимость от какого-либо оконного менеджера. Он взаимодействует с окнами посредством протокола EWMH/NetWM, который поддерживают большинство оконных менеджеров.
Не буду утомлять тебя рассказами о возможностях утилиты и ее флагах, а сразу покажу пример. Все знают о существовании Yakuake и Tilda, специальных эмуляторов терминала, которые можно разворачивать и сворачивать нажатием клавиши. С помощью wmctrl ты можешь наделить такими возможностями любой другой эмулятор терминала (например, Konsole из KDE).
#! /bin/bash
if [ `wmctrl -xl | grep -c Konsole` != 0 ]; then
if [ -f /tmp/.Konsole.add ]; then
wmctrl -r Konsole -b add,below
rm /tmp/.Konsole.add
else
wmctrl -r Konsole -b add,above
touch /tmp/.Konsole.add
fi
else
konsole
fi
Просто повесь его на клавиатурную комбинацию. Первое нажатие запустит терминал, а все последующие будут сворачивать/разворачивать его.
Эмулятор терминала не единственное применение wmctrl в рамках представленного выше скрипта. На самом деле вместо Konsole можно подставить любую программу. А можно пойти дальше и задействовать в сценарии два окна, например браузер и мессенджер, таким образом, чтобы в определенный момент работы в интернете нажатием клавиш можно было заставить браузер подвинуться и освободить место под мессенджер и кинуть взгляд на сообщения в чате.
Чтобы этого добиться, сначала нужно определить размеры окон обоих приложений в каждом из двух требующихся состояний. Делается это с помощью команды wmctrl -lG (перед этим растяни/сожми окна до нужных размеров):
$ wmctrl -lG
0x0500001b 0 0 55 1280 726 N/A Проект OpenNet - QupZilla
0x03000005 0 900 55 380 693 N/A Telegram (6)
$ wmctrl -lG
0x0500001b 0 0 55 900 693 N/A Проект OpenNet - QupZilla
0x03000005 0 900 55 380 693 N/A Telegram (6)
Опция -G добавляет четыре дополнительных столбца в середине вывода команды. В них отражены данные о смещении окон по осям X и Y, а также их ширина и высота соответственно. В моем случае я сначала использовал данные в точности, как их вывела команда. Но при подстановке в сценарий расположение окна QupZilla по оси Y по какой-то причине отличалось от расчетного, поэтому его пришлось немного подкорректировать вручную.
#!/bin/sh
if [ -f /tmp/.telega.half ]; then
wmctrl -r Telegram -e '0,900,55,380,693' -b add,below
wmctrl -r QupZilla -e '0,0,26,1280,726'
rm /tmp/.telega.half
else
wmctrl -r QupZilla -e '0,0,26,900,693'
wmctrl -r Telegram -e '0,900,55,380,693' -b remove,below
touch /tmp/.telega.half
fi
При первом запуске этот скрипт сожмет окно браузера с правой стороны и покажет в освободившемся пространстве окно мессенджера. Второй запуск закроет мессенджер и вернет окно браузера в прежнее состояние.

Xdotool
Telegram, который мы использовали в примере с браузером и мессенджером, сам по себе неплохо управляется сочетаниями клавиш. И все-таки одного шортката мне не хватает. Того, который восстанавливал бы окно из лотка. Wmctrl не всегда способен решить эту задачу. И пока встроенные возможности мессенджера не могут нас порадовать подобной функциональностью, поможет утилита xdotool. Она позволяет эмулировать действия мышью, а значит, и повесить их на сочетания клавиш.
Поскольку рабочее окружение у меня Plasma, я создал еще один виджет системного лотка, отключив в его настройках все пункты, кроме «Состояния приложений», а всем элементам приложений, кроме Telegram, указал пожизненную невидимость («Всегда скрывать»). Сам же Telegram должен быть всегда виден.

Осталось только определить координаты значка «Телеграма» при заблокированных виджетах, установив на него курсор мыши и выполнив в терминале такую команду:
$ xdotool getmouselocation

Из всего многообразия полученных данных берем координаты X, Y (в моем случае — 1238 и 776) и подставляем в команду, перемещающую курсор мыши в заданное положение из любой области экрана и эмулирующую одно нажатие левой кнопки.
#!/bin/sh
xdotool mousemove 1238 776 click 1 mousemove 640 400
Далее скрипт можно привязать к комбинации клавиш (или, как у меня, к одной — Menu), чтобы при их нажатии появлялось окно программы. Повторное нажатие того же сочетания клавиш вновь свернет окно Telegram в трей. Для удобства навигации в скрипт добавлен возврат курсора мыши в центр экрана.
Xwininfo
Утилита xwininfo показывает на экране большое количество характеристик выбранного окна: ID, название, размеры, отступы от краев экрана, толщину границ, цветовую палитру и многое другое. Утилита wmctrl, содержащая в строке параметров опцию :SELECT:, позволяет применить указанные параметры к окну, наведя на него курсор и щелкнув мышью:
$ wmctrl -r :SELECT: -T <название>
Xprop
Часто используемая в различных сценариях утилита xprop предназначена для отображения свойств окон и шрифтов. В некоторых моментах функциональность xprop пересекается с функциональностью других утилит. Например, чтобы определить активное окно, можно выполнить одну из следующих команд:
$ xdotool getwindowname $(xdotool getactivewindow)
$ xwininfo -int -id $(xdotool getactivewindow) | awk -F\" '/xwininfo:/ { print $2; exit }'
$ xwininfo -id $(xprop -root | awk '/NET_ACTIVE_WINDOW/ { print $5; exit }') | awk -F\" '/xwininfo:/ { print $2; exit }'
Кроме того, xprop можно использовать, когда нужно изменить свойства окон или шрифтов. В одной из прошлых статей я рассказывал про трюк с эффектом размытия для полупрозрачного окна Yakuake. Тот же прием для Konsole будет выглядеть так:
#!/bin/bash
if [ `echo $DISPLAY` ]; then
konsolex=$(qdbus | grep konsole | cut -f 2 -d\ )
if [ -n konsolex ]; then
for konsole in $konsolex; do
xprop -f _KDE_NET_WM_BLUR_BEHIND_REGION 32c -set _KDE_NET_WM_BLUR_BEHIND_REGION 0 -id `qdbus $konsole /konsole/MainWindow_1 winId`;
done
fi
fi
D-Bus
Практически любой современный десктопный дистрибутив Linux поставляется с системой межпроцессного взаимодействия D-Bus. Многие приложения используют D-Bus для общения между собой, ее же использует среда KDE с версии 4. Для нас же важно то, что D-Bus можно применить в качестве посредника между пользователем и машиной, то есть для управления графическими приложениями и их скриптования.
Как пример использования D-Bus приведу скрипт, который мониторит уведомления от Telegram и при наличии в сообщении определенного триггера — имени контакта или ключевой фразы — автоматически открывает приложение для просмотра сообщения. Чтобы реализовать этот замысел, можно присовокупить к D-Bus уже известный нам xdotool:
#!/bin/bash
contact="Николай"
dbus-monitor "interface='org.freedesktop.Notifications'" |\
grep --line-buffered "string" |\
grep --line-buffered $contact |\
grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v |\
grep --line-buffered '.*(?=string)|(?<=string).*' -oPi |\
grep --line-buffered -v '^\s*$' |\
xargs -I '{}' echo {} |\
sed -u -n 's/'$contact'/xdotool mousemove 1096 66 sleep 1 click 1/p' |\
sh
В качестве триггера здесь использовано имя контакта, как оно указано в списке контактов. Фильтруя и редактируя новые сообщения в рамках мониторинга D-Bus, на выходе получаем имя контакта в момент, когда от него приходит сообщение, и подменяем его на модифицированную команду из предыдущих примеров.
По заранее вычисленным координатам скрипт перемещает курсор мыши в ту область, где появляется окно нотификации, и секунду спустя эмулирует клик левой кнопки, тем самым заставляя «Телеграм» открываться с фокусом на отправителе этого сообщения и самом сообщении.
Выводы
Несмотря на то что графический софт обычно предполагает управление мышью и зачастую весьма ограниченный набор комбинаций клавиш, широкие возможности Linux позволяют создавать сценарии даже в этом случае.
В статье перечислены далеко не все возможности консольных приложений по управлению программами с графическим интерфейсом. Тут предпринята всего лишь попытка обозначить наиболее общие моменты, с помощью которых каждый мог бы настроить собственный инструментарий для выполнения своих уникальных задач.










